-- 修改bucket为DepMap

-- target -> {key} -> {effect}
local bucket = {};

-- 作为内部存储数据的
local symbol = {}
-- 存储当前副作用
local activeEffect

local metatable = {
    __index = function(target, key)
        print("track", target, key)
        -- 待触发函数
        if (type(activeEffect) == "function") then
            -- bucket -> targetTable(depsMap)
            local depsMap = bucket[target]
            if type(depsMap) ~= 'table' then
                depsMap = {};
                bucket[target] = depsMap
            end

            -- depsMap -> keyTable(deps)
            local deps = depsMap[key]
            if type(deps) ~= "table" then
                deps = {}
                depsMap[key] = deps
            end
            -- deps -> effect
            table.insert(deps, activeEffect)
        end
        return target[symbol][key]
    end,
    __newindex = function(target, key, value)
        print("trigger", target, key)
        local oldValue = target[symbol][key]
        target[symbol][key] = value

        if (oldValue ~= value) then
            -- 读取depsMap
            local depsMap = bucket[target]
            if (type(depsMap) ~= "table") then
                return
            end
            local deps = depsMap[key]
            if (type(deps) ~= 'table') then
                return
            end
            -- deps遍历
            for i = 1, #deps, 1 do
                local fn = deps[i]
                if (type(fn) == "function") then
                    fn();
                end
            end
        end
    end
}

-- 代理数据
local function reactive(table)
    local proxy = {}
    proxy[symbol] = table
    setmetatable(proxy, metatable)
    return proxy
end

-- 转换为代理数据
local data = reactive({ text = "hello", other = '321' })

function effect(fn)
    if (type(fn) == "function") then
        activeEffect = fn
        fn()
    end
    activeEffect = nil
end

effect(function()
    print("effect run")
    local i = data.text
    print("i", i);
end);


data.text = "fix value"
data.other = "dd"
data.text = "fix value1"

